package genedit.utility;

import genedit.model.graph.ConnectionPoint;
import genedit.model.graph.GraphElement;
import genedit.model.graph.Link;
import genedit.model.graph.MyRect;
import genedit.model.graph.SubdocumentElement;
import genedit.model.graph.classModel.AggregationLink;
import genedit.model.graph.classModel.AssociationLink;
import genedit.model.graph.classModel.ClassModel;
import genedit.model.graph.classModel.CompositionLink;
import genedit.model.graph.classModel.GeneralizationLink;
import genedit.model.graph.classModel.InterfaceModel;
import genedit.view.graph.AggregationLinkPainter;
import genedit.view.graph.AssociationLinkPainter;
import genedit.view.graph.ClassModelPainter;
import genedit.view.graph.CompositionLinkPainter;
import genedit.view.graph.ElementPainter;
import genedit.view.graph.GeneralizationLinkPainter;
import genedit.view.graph.InterfaceModelPainter;
import genedit.view.graph.LinkPainter;
import genedit.view.graph.MyRectPainter;
import genedit.view.graph.SubdocumentElementPainter;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Iterator;

@SuppressWarnings("rawtypes")
public class PainterMap {
	private HashMap<String, Class> painterMap = new HashMap<String, Class>();

	private static PainterMap instance = null;

	public static PainterMap getInstance() {
		if (instance == null) {
			instance = new PainterMap();
		}
		return instance;
	}

	protected PainterMap() {
		// Link
		painterMap.put(MyRect.class.getName(), MyRectPainter.class);
		painterMap.put(Link.class.getName(), LinkPainter.class);
		painterMap.put(SubdocumentElement.class.getName(), SubdocumentElementPainter.class);
		//
		painterMap.put(ClassModel.class.getName(), ClassModelPainter.class);
		painterMap.put(InterfaceModel.class.getName(), InterfaceModelPainter.class);
		painterMap.put(AssociationLink.class.getName(), AssociationLinkPainter.class);
		painterMap.put(GeneralizationLink.class.getName(), GeneralizationLinkPainter.class);
		painterMap.put(AggregationLink.class.getName(), AggregationLinkPainter.class);
		painterMap.put(CompositionLink.class.getName(), CompositionLinkPainter.class);
	}

	public ElementPainter getPainter(GraphElement graphElement) {
		Class painterClass = painterMap.get(graphElement.getClass().getName());
		if (painterClass == null)
			return null;
		Constructor[] painterConstructors = painterClass.getConstructors();
		ElementPainter painter = null;
		for (Constructor constructor : painterConstructors) {
			if (constructor.getParameterTypes().length == 1
					&& constructor.getParameterTypes()[0].getName().equals(
							GraphElement.class.getName())) {
				try {
					painter = (ElementPainter) constructor.newInstance(graphElement);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
		for (ConnectionPoint cp : graphElement.getConnectionPoints()){
			Iterator<Link> linkIt = cp.getIteratorStarting();
	
			while (linkIt.hasNext()) {
				linkIt.next().getStart().setActive(true);
			}
	
			linkIt = cp.getIteratorEnding();
	
			while (linkIt.hasNext()) {
				linkIt.next().getEnd().setActive(true);
			}
		}
		
		return painter;
	}
}
